<?php if (!defined('BASEPATH')) exit('No direct script access allowed');
/** An auth CI class **
 This class is for authentication purposes. It must be configured via the CI's config file.
*/

/** TO-FIX :
 - Do single class that delegates the stuffs to be composable on other classes.
 - Add the group stuff.
*/
class Auth{
	
	var $session;
	var $username;
	var $ci;
	var $delegates;
	var $is_valid;
	var $user;
	static public $challenge;
	//var $
	
	function Auth ($args = null) {
		// Gets CI and session instances
		$this->ci =& get_instance();
		$this->user = Ar::ar_factory('users');
		self::$challenge = random_string('unique');
		$this->load->vars(array('challenge' => self::$challenge));
		$this->is_valid = false;
		$this->delegates = array();
	}
	
	// Forward all calls to the CI object after check if isn't a Delegate call
	function __call($m, $args) {
		// Check if is calling a delegate
		if (strpos($m, 'del_') !== false) {
			if (array_key_exists($m, $this->delegates)) {
				foreach ($this->delegates as $del) {
					$del->$m($args);
				}
			}
			return;
		}
		return $this->ci->$m($args);
	}
	
	function __set($n, $v) {
		$this->ci->$n = $v;
	}

	function __get($n) {
		return $this->ci->$n;
	}

	
	function validate_registration() {
		$this->is_valid = false;
		$this->load->library('validation');
    
    /* Configuring Rules */
    $rules['username']  = "trim|required|alpha_dash|min_length[5]|max_length[15]|xss_clean";
//    $rules['username'] .= "callback_unique_user";
    $rules['password']  = "trim|required|matches[passconf]";
    $rules['passconf']	= "trim|required";
    $rules['email']     = "trim|required|callback_valid_email";//|callback_unique_mail";
    $rules['challenge'] = "trim|required|callback_valid_challenge";
    $this->validation->set_rules($rules);
    
    /* Configuring Fields */
    $fields['username']	= 'Username';
    $fields['password']	= 'Password';
    $fields['passconf']	= 'Password Confirmation';
    $fields['email']	= 'Email Address';
    $this->validation->set_fields($fields);
    
		$this->del_before_validate_registration($this);
		
		$this->is_valid = $this->validation->run();
		return $this->is_valid;
	}
	
	function validate_login() {
		$this->is_valid = false;
		$this->load->library('validation');
    
    /* Configuring Rules */
    $rules['username']  = "trim|required|alpha_dash|min_length[5]|max_length[15]|callback_exist_user|xss_clean";
    $rules['password']  = "trim|required";
    $rules['challenge'] = "trim|required|valid_challenge";
    $this->validation->set_rules($rules);
    
    /* Configuring Fields */
    $fields['username']	= 'Username';
    $fields['password']	= 'Password';
    $this->validation->set_fields($fields);
    
		$this->del_before_validate_login($this);
		
		$this->is_valid = $this->validation->run();
		return $this->is_valid;
	}
	
	function create_user($data) {
		$res = false;
		if (($this->validation && $this->is_valid === true) || (array_key_exists('is_valid', $data) &&
				$data['is_valid'] === true)) {
			$this->user->username = $data['username'];
			$this->user->password = $data['password'];
			$this->user->email = $data['email'];
			$this->user->session_id = $this->session->userdata('session_id');
//			$this->user->group = '';
			$this->user->is_active = false;
			if ($this->user_is_unique($this->user->username))
				$res = $this->user->save();
			return $res;
		}
		return false;
	}
	
	function login_user($data) {
		// Policy, session[login] must be false.
		$s_login = $this->session->userdata('login');
		if ($s_login == false && (($this->validation && $this->is_valid === true) || 
			(array_key_exists('is_valid', $data) && $data['is_valid'] === true))) {
			if ($this->check_db($data['username'], $data['password']) === true) {
				$this->session->set_userdata(array('login' => 'TRUE', 'rememberme' => 0, 
																					'sess_expiration' => 0));
				if (strlen($this->input->post('rememberme')))
					$this->session->set_userdata(array('sess_expiration' => 2592000, 'rememberme' => 1));
				return true;
			}
		}
		return false;
	}
	
	function logout_user() {
		$this->session->sess_destroy();
	}
	
	function activate_user($name, $sess_id) {
		$res = $this->user->load(array('username' => $name, 'session_id' => $sess_id, 'is_active' => false));
		if ($res !== false) {
			$this->user->is_active = true;
			$this->user->save();
		}
	}
	
	/* Checks methods */
	function check_session() {
		if ($this->session->userdata('login') == 'TRUE') {
			return $this->user->load(array('username' => $this->session->userdata('username'), 
																		'session_id' => $this->session->userdata['session_id'],
//																		'group' => $this->session->userdata['group']),
																		'is_active' => true));
		}
		return false;
	}
	
	function check_db($name, $pass, $group = null) {
		return $this->user->load(array('username' => $name,
																	'password' => $pass,
//																'group' => $group,
																	'is_active' => true));
	}
		
	/* Methods to improve on, could change */
	function set_delegate($handle, $delegate) {
		$this->delegates['del_'.$handle][] = $delegate;
	}
	
	function set_view($name, $view, $data = null) {
		
	}
  function check_challenge($cha){
  	return ($cha != false && $this->ci->session->userdata('challenge') != false && 
  					$this->ci->session->userdata('challenge') == $cha);
  }
	
	/* Validation callbacks */
  private function exist_user($to_check) {
    $this->validation->set_message('exist_user', 'An error has ocurred. Please try again.');
    return !$this->user_is_unique($to_check);
  }

  private function unique_user($to_check) {
    $this->validation->set_message('unique_user', 'The Username you chose already exist.');
    return $this->user_is_unique($to_check);
  }
  
  private function unique_mail($to_check) {
    $this->validation->set_message('unique_mail', 'The Email you enter already was used by other user.');
    return $this->useremail_is_unique($to_check);
  }
  
  private function valid_challenge($cha) {
  	$this->validation->set_message('valid_challenge', 'An error has ocurred. Please try again.');
  	return $this->check_challenge($cha);
  }
  /* Validation custom methods */
  function useremail_is_unique($u) {
  	//Load returns true if could load the user, so already exists an email, isn't unique.
  	$ret = !$this->user->load(array('email' => $u));
  	$this->user->reset_vals();
  	return $ret;
  }
  function user_is_unique($u) {
  	$ret = !$this->user->load(array('username' => $u));
  	$this->user->reset_vals();
  	return $ret;
  }
}
?>